package product

// 具体聚合 - 树形分类目录
type TreeAggregate struct {
	Root *Category
}

type Category struct {
	Name     string
	Products []*Product
	Children []*Category
}

func NewTreeAggregate() *TreeAggregate {
	// 构建树形结构
	electronics := &Category{Name: "电子产品"}

	computers := &Category{Name: "电脑"}
	computers.Products = []*Product{
		{101, "MacBook Pro", 12999},
		{102, "Surface Laptop", 8999},
	}

	phones := &Category{Name: "手机"}
	phones.Products = []*Product{
		{201, "iPhone 15", 6999},
		{202, "Samsung Galaxy", 5999},
	}

	electronics.Children = []*Category{computers, phones}

	home := &Category{Name: "家居用品"}

	furniture := &Category{Name: "家具"}
	furniture.Products = []*Product{
		{301, "办公椅", 599},
		{302, "书桌", 1299},
	}

	kitchen := &Category{Name: "厨房用品"}
	kitchen.Products = []*Product{
		{401, "不粘锅", 299},
		{402, "刀具套装", 399},
	}

	home.Children = []*Category{furniture, kitchen}

	return &TreeAggregate{
		Root: &Category{
			Name:     "根目录",
			Children: []*Category{electronics, home},
		},
	}
}

// CreateIterator 创建迭代器
func (r *TreeAggregate) CreateIterator() Iterator {
	return &TreeIterator{
		aggregate: r,
	}
}

// TreeIterator 树形迭代器 - 深度优先遍历
type TreeIterator struct {
	aggregate *TreeAggregate
	stack     []*Category // 存储当前遍历路径
	indexes   []int       // 存储每个层级当前索引
	current   *Product    // 当前产品
}

func (i *TreeIterator) HasNext() bool {
	// 如果当前有缓存的产品，直接返回
	if i.current != nil {
		return true
	}

	// 深度优先遍历
	for len(i.stack) > 0 {
		currentLevel := len(i.stack) - 1
		currentCategory := i.stack[currentLevel]
		currentIndex := i.indexes[currentLevel]

		// 检查当前分类的产品
		if currentIndex < len(currentCategory.Products) {
			i.current = currentCategory.Products[currentIndex]
			i.indexes[currentLevel] = currentIndex + 1
			return true
		}

		// 检查子分类
		if currentIndex-len(currentCategory.Products) < len(currentCategory.Children) {
			childIndex := currentIndex - len(currentCategory.Products)
			child := currentCategory.Children[childIndex]

			// 进入子分类
			i.stack = append(i.stack, child)
			i.indexes = append(i.indexes, 0)
			i.indexes[currentLevel] = currentIndex + 1
			continue
		}

		// 当前分类遍历完成，回溯
		i.stack = i.stack[:currentLevel]
		i.indexes = i.indexes[:currentLevel]
	}

	return false
}

func (i *TreeIterator) Next() interface{} {
	if !i.HasNext() {
		return nil
	}
	product := i.current
	i.current = nil
	return product
}

func (i *TreeIterator) Reset() {
	i.stack = []*Category{i.aggregate.Root}
	i.indexes = []int{0}
	i.current = nil
}
